/* 通用 CRUD 接口 */

// 导出严格函数并接收一个参数app
module.exports = app => {
  const express = require('express')

  // 导入使用第三方模块jsonwebtoken的sign方法来生成token
  const jwt = require('jsonwebtoken')
  // 错误处理中间件(第三方)
  const assert = require('http-assert')
  // 引用用户模型，通过用户名查找用户
  const AdminUser = require('../../models/AdminUser')
  // 引入登录校验中间件(自定义)
  const authMiddleware = require('../../middleware/auth')
  // 引入模板处理引入中间件(自定义)
  const resourceMiddleware = require('../../middleware/resource')

  const router = express.Router()

  // 请求添加接口
  router.post('/',async (req,res) => {
    const model = await req.Model.create(req.body)
    res.send(model)
  })

  // 修改接口
  router.put('/:id',async (req,res) => {
    const model = await req.Model.findByIdAndUpdate(req.params.id,req.body)
    res.send(model)
  })

  // 删除（根据id查询）接口
  router.delete('/:id',async (req,res) => {
    await req.Model.findByIdAndDelete(req.params.id,req.body)
    res.send({
      success:true
    })
  })

  // 查询数据接口
  router.get('/',async (req,res) => {
    // populate('parent')获取parent整个对象（查询返回指定字段）
    const queryOptions = {}
    if(req.Model.modelName === 'Category'){
      queryOptions.populate = 'parent'
    }
    const items = await req.Model.find().setOptions(queryOptions).limit(100)
    res.send(items)
  })

  // 根据id查询数据接口
  router.get('/:id',async (req,res) => {
    const model = await req.Model.findById(req.params.id)
    res.send(model)
  })

  app.use('/admin/api/rest/:resource',authMiddleware(),resourceMiddleware(),router)

  // 图片上传接口
  /**
   * multer 图片上传处理中间件
   */
  const multer = require('multer')
  const upload = multer({dest:__dirname + '/../../uploads'})
  app.post('/admin/api/upload',authMiddleware(),upload.single('file'),async (req,res) => {
    // 使用multer中间件处理的文件路径会自动挂载到req上
    const file = req.file
    file.url = `http://localhost:3000/uploads/${file.filename}`
    res.send(file)
  })

  // login登录接口
  app.post('/admin/api/login',async (req,res)=>{
    const { username,password } = req.body
    // 1.根据用户名找用户
    // 在模块中密码设置selset为false-无法获取，.select('+password')表示需要获取密码
    const user = await AdminUser.findOne({username}).select('+password')
    // 判断用户是否存在，若不存在则返回提示信息和不正常状态码
    assert(user,422,'用户不存在')
    // if(!user){
    //   return res.status(422).send({
    //     message:'用户不存在'
    //   })
    // }

    // 2.校验密码
    // 使用bcrypt模块（加密）校验密码 返回一个布尔值
    const isVaild = require('bcrypt').compareSync(password,user.password)
    assert(isVaild,422,'密码错误')
    // 3.返回token
    /**
     * 参数：
     *      1.需要加密的数据（或需要放在token中的数据）
     *      2.密钥
     *      app.get('secret') 当只有一个参数时表示获取变量secret
     */
    const token = jwt.sign({id:user._id},app.get('secret'))
    res.send(token)
  })

  // 错误处理函数
  app.use(async (err,req,res,next) => {
    res.status(err.statusCode).send({
      message:err.message
    })
  })
}